package com.honey.mybatis.generator.dependent;

import com.honey.compilation.java.JavaVisibility;
import com.honey.compilation.java.MethodDecoration;
import com.honey.core.dbmapping.structure.Structure;
import com.honey.core.types.FullyQualifiedJavaType;
import com.honey.mybatis.generator.AbstractMybatis;
import com.honey.mybatis.generator.MybatisPlugin;
import com.honey.mybatis.generator.condition.ConditionConstant;
import com.honey.mybatis.generator.criteria.CriteriaConstant;
import com.honey.mybatis.generator.entity.EntityConstant;
import com.honey.mybatis.generator.inversion.InversionModel;


/**
 * dao 的依赖模型
 * @author Administrator
 *
 */
public enum DependentModel {

	/** 注入模型  */
	INJECTION{
		
		private DependentMapperId dependentMapperId = null;
		
		public String call(InversionModel m ){
			return "baseMybatisdao.";
		}
		
		@Override
		public MethodDecoration getMethodDecoration(InversionModel injectionModel){
			return new MethodDecoration(JavaVisibility.PUBLIC,false,true);
		}
		
		@Override
		public DependentMapperId getDependentMapperId(){
			if( dependentMapperId == null ){
				dependentMapperId = new InjectionMapperId();
			}
			return dependentMapperId;
		}
		
		@Override
		public String getEntityVariable(MybatisPlugin belongPlugin,Structure schema){
			return new AbstractMybatis( belongPlugin ){
				@Override
				//小心陷入无限的递归调用中
				public String getEntityVariableName(Structure schema) {
					return  mybatisPlugin.getJavaNameCalculator().variableNameCalculator(schema.getJavaProperty(),mybatisPlugin.getEntityClassSuffix());
				}
			}
			.getEntityVariableName(schema);
		}
		
		@Override
		public String getEntityClassName(MybatisPlugin belongPlugin,Structure schema){
			return new AbstractMybatis( belongPlugin ){
				@Override
				//小心陷入无限的递归调用中
				public String getEntityClassName(Structure schema) {
					return getClassName(schema, mybatisPlugin.getEntityClassSuffix());
				}
			}
			.getEntityClassName(schema);
		}
		
		@Override
		public FullyQualifiedJavaType getEntityClassType(MybatisPlugin belongPlugin,Structure schema){
			return  new AbstractMybatis( belongPlugin ){
				@Override
				//小心陷入无限的递归调用中
				public FullyQualifiedJavaType getEntityClassType(Structure schema) {
					return getClassType(schema, mybatisPlugin.getEntityTargetPackage(),mybatisPlugin.getEntityClassSuffix(),null);
				}
			}
			.getEntityClassType(schema);
		}
		
		@Override
		public FullyQualifiedJavaType getConditionClassType(MybatisPlugin belongPlugin,Structure schema){
			return  new AbstractMybatis( belongPlugin ){
				@Override
				//小心陷入无限的递归调用中
				public FullyQualifiedJavaType getConditionClassType(Structure schema) {
					return new FullyQualifiedJavaType(mybatisPlugin.getModelTargetPackage(),ConditionConstant.CONDITION_CLASS_NAME+"<"+getModelClassName(schema)+">");
				}
			}
			.getConditionClassType(schema);
		};
		
		@Override
		public String getModelClassName(MybatisPlugin belongPlugin,Structure schema){
			return  new AbstractMybatis( belongPlugin ){
				@Override
				//小心陷入无限的递归调用中
				public String getModelClassName(Structure schema) {
					return getClassName(schema, mybatisPlugin.getModelClassSuffix());
				}
			}.getModelClassName(schema);
		}
		
		@Override
		public FullyQualifiedJavaType getModelClassType(MybatisPlugin belongPlugin,Structure schema){
			return  new AbstractMybatis( belongPlugin ){
				@Override
				//小心陷入无限的递归调用中
				public FullyQualifiedJavaType getModelClassType(Structure schema) {
					return getClassType(schema, mybatisPlugin.getModelTargetPackage(),mybatisPlugin.getModelClassSuffix(),null);
				}
			}.getModelClassType(schema);
		}
	},

	/** 继承模型 */
	EXTEND{
		private DependentMapperId dependentMapperId = null;
		
		public String call(InversionModel m ){
			String answer = null;
			if(m ==InversionModel.EXTEND){
				answer="super." ;
			}else{
				answer = "this.";
			}
			return answer;
		}
		
		@Override
		public MethodDecoration getMethodDecoration(InversionModel injectionModel){
			return new MethodDecoration(JavaVisibility.PROTECTED,false,true);
		}
		
		@Override
		public DependentMapperId getDependentMapperId(){
			if( dependentMapperId == null){
				dependentMapperId = new ExtendMapperId();
			} 
			return dependentMapperId;
		}
		
		@Override
		public String getEntityVariable(MybatisPlugin belongPlugin,Structure schema){
			return "entity";
		}
		
		@Override
		public String getEntityClassName(MybatisPlugin belongPlugin,Structure schema){
			return EntityConstant.ENTITY_GENERIC_NAME;
		}
		
		@Override
		public FullyQualifiedJavaType getEntityClassType(MybatisPlugin belongPlugin,Structure schema){
			return EntityConstant.ENTITY_GENERIC_TYPE;
		}
		
		@Override
		public FullyQualifiedJavaType getConditionClassType(MybatisPlugin belongPlugin,Structure schema){
			return  new AbstractMybatis( belongPlugin ){
				@Override
				//小心陷入无限的递归调用中
				public FullyQualifiedJavaType getConditionClassType(
						Structure schema) {					
					return new FullyQualifiedJavaType(mybatisPlugin.getModelTargetPackage(),ConditionConstant.CONDITION_CLASS_NAME+"< ? extends "+CriteriaConstant.GENERATED_CRITERIA_CLASS_NAME+">");
				}
			}.getConditionClassType(schema);
		};
		
		@Override
		public String getModelClassName(MybatisPlugin belongPlugin,Structure schema){
			return CriteriaConstant.GENERATED_CRITERIA_CLASS_NAME;
		}
		
		@Override
		public FullyQualifiedJavaType getModelClassType(MybatisPlugin belongPlugin,Structure schema){
			return new FullyQualifiedJavaType(belongPlugin.getModelTargetPackage(),CriteriaConstant.GENERATED_CRITERIA_CLASS_NAME);
		}
	},
	;
	
	public abstract String call(InversionModel injectionModel);
	
	public abstract MethodDecoration getMethodDecoration(InversionModel injectionModel);
	
	public abstract DependentMapperId getDependentMapperId();
	
//-------------------------------------------------------------------------------------------	
	
	/**
	 * entity 对象提升或降级情况如下:<br />
	 * extend 模型时对象提升到父类<br />
	 * injection 模型时对象降级到子类(实现类) <br />
	 */
	public abstract String getEntityClassName(MybatisPlugin belongPlugin,Structure schema);
	
	/**
	 * entity 对象提升或降级情况如下:<br />
	 * extend 模型时对象提升到父类<br />
	 * injection 模型时对象降级到子类(实现类)<br />
	 */
	public abstract FullyQualifiedJavaType getEntityClassType(MybatisPlugin belongPlugin,Structure schema);
	
	/**
	 * entity 对象提升或降级情况如下:<br />
	 * extend 模型时对象提升到父类<br />
	 * injection 模型时对象降级到子类(实现类)<br />
	 */
	public abstract String getEntityVariable(MybatisPlugin belongPlugin,Structure schema);
	
	/**
	 * condition 对象提升或降级情况如下:<br />
	 * extend 模型时对象提升到父类<br />
	 * injection 模型时对象降级到子类(实现类)<br />
	 */
	public abstract FullyQualifiedJavaType getConditionClassType(MybatisPlugin belongPlugin,Structure schema);
	

	/**
	 * Model 对象提升或降级情况如下:<br />
	 * extend 模型时对象提升到父类<br />
	 * injection 模型时对象降级到子类(实现类)<br />
	 */
	public abstract String getModelClassName(MybatisPlugin belongPlugin,Structure schema);
	
	/**
	 * Model 对象提升或降级情况如下:<br />
	 * extend 模型时对象提升到父类<br />
	 * injection 模型时对象降级到子类(实现类)<br />
	 */
	public abstract FullyQualifiedJavaType getModelClassType(MybatisPlugin belongPlugin,Structure schema);
	
}
